package leetcode; /**
 * description:
 * author:张腾
 * date:2021-06-14
 */

import java.util.*;

/**
 * 给你一个整数数组 nums ，其中可能包含重复元素，请你返回该数组所有可能的子集（幂集）。
 *
 * 解集 不能 包含重复的子集。返回的解集中，子集可以按 任意顺序 排列。
 */
public class leetcode90 {

    List<List<Integer>> res;
    List<Integer> path;
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        res = new ArrayList<>();
        path = new ArrayList<>();
        // 首先排序，让相同的两个元素排到一起去，便于去重
        Arrays.sort(nums);
        int n = nums.length;
        // 使用 visited 数组来记录哪一个元素在当前路径中被使用了
        boolean[] visited = new boolean[n];
        // 开始回溯
        resBack(nums, 0, visited, n);
        return res;
    }

    public void resBack(int[] nums,int index,boolean[] visited,int n){
        res.add(new ArrayList<>(path));

        for (int i = index;i < n;i++){
            //去重
            // 如果当前元素和前一个元素相同，而且前一个元素没有被访问，说明前一个相同的元素在当前层已经被用过了
            if (i>0 && nums[i-1]==nums[i] && !visited[i-1]) continue;

            visited[i] = true;
            path.add(nums[i]);
            resBack(nums,i+1,visited,n);
            path.remove(path.size()-1);
            visited[i] = false;
        }
    }
}
